library popup;

import 'dart:async';
import 'dart:math';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:top_foundation/utils/theme/theme.dart';
import 'package:whale/helper/utils/popup/bottom_input.dart';
import 'package:whale/helper/utils/popup/notice.dart';

import '../util.dart';
import 'alert.dart';
import 'bottom.dart';
import 'drop_down.dart';

mixin PopupDelegate {}

class Popup {
  static const double _defaultScrollControlDisabledMaxHeightRatio = 9.0 / 16.0;

  static TextStyle unSelectedStyle = ITheme.text.title16;
  static TextStyle selectedStyle =
      TextStyle(color: ITheme.selectedColor, fontSize: 16.sp);

  static double get itemHeight => 44.r;

  static FutureOr<T?> dialog<T>({
    required Widget child,
    bool barrierDismissible = false,
  }) async {
    if (Get.context == null) return null;
    return showCupertinoDialog(
        context: Get.context!,
        barrierDismissible: barrierDismissible,
        builder: (_) => child);
  }

  static FutureOr<T?> alert<T>({
    String? title,
    String? msg,
    Widget? content,
    String? cancelText = '取消',
    String? sureText = '确定',
    Color? cancelColor,
    Color? sureColor,
    BoolResultCallback? conditionDismiss,
    bool hasHeaderLine = false,
    bool hasFooterLine = true,
    EdgeInsets? margin,
    Color? backgroundColor,
  }) async {
    if (Get.context == null) return null;
    return showCupertinoDialog(
      context: Get.context!,
      builder: (c) => PopupAlertView(
        title: title,
        msg: msg,
        content: content,
        cancelColor: cancelColor,
        cancelText: cancelText,
        sureColor: sureColor,
        sureText: sureText,
        conditionDismiss: conditionDismiss,
        hasFooterLine: hasFooterLine,
        hasHeaderLine: hasHeaderLine,
        margin: margin ?? EdgeInsets.symmetric(horizontal: 0.2.sw),
        backgroundColor: backgroundColor,
      ),
    );
  }

  static FutureOr<T?> bottom<T>({
    required Widget child,
  }) async {
    if (Get.context == null) return null;

    return showCupertinoDialog(
        context: Get.context!,
        builder: (_) => Column(
              mainAxisAlignment: MainAxisAlignment.end,
              children: [
                child,
              ],
            ));
  }

  static FutureOr<T?> bottomInput<T>({
    required String title,
    required ValueChanged<String> onChanged,
    BoolResultCallback? conditionDismiss,
    final Color? backgroundColor,
  }) async {
    if (Get.context == null) return null;
    return bottom(
        child: DialogInputBottom(
      title: title,
      onChanged: onChanged,
      conditionDismiss: conditionDismiss,
    ));
  }

  static FutureOr<T?> bottomSheet<T>({
    required List<String> data,
    required void Function(int) onTap,
    final TextStyle? unSelectedStyle,
    final TextStyle? selectedStyle,
    final int? initIndex,
    final Color? backgroundColor,
    final double? itemHeight,
    final bool isFixSize = true,
  }) async {
    if (Get.context == null) return null;

    var ratio = isFixSize
        ? _getBottomRatio(itemHeight: itemHeight, length: data.length)
        : _defaultScrollControlDisabledMaxHeightRatio;
    return showModalBottomSheet(
        context: Get.context!,
        backgroundColor: backgroundColor,
        constraints: BoxConstraints.expand(width: 1.sw),
        scrollControlDisabledMaxHeightRatio: ratio,
        builder: (_) => PopupBottomListView(
              data: data,
              initIndex: initIndex,
              onTap: onTap,
              unSelectedStyle: unSelectedStyle,
              selectedStyle: selectedStyle,
              itemHeight: itemHeight,
            ));
  }

  static FutureOr<T?> bottomRadioSheet<T>({
    required List<String> data,
    required ValueChanged<List<int>> onSure,
    TextStyle? unSelectedStyle,
    TextStyle? selectedStyle,
    List<int>? initIndexs,
    bool isSingleSelect = true,
    String? title,
    Color? backgroundColor,
    final bool isFixSize = false,
  }) async {
    if (Get.context == null) return null;
    var ratio = isFixSize
        ? _getBottomRatio(itemHeight: itemHeight, length: data.length)
        : _defaultScrollControlDisabledMaxHeightRatio;
    return showModalBottomSheet(
        context: Get.context!,
        backgroundColor: backgroundColor,
        constraints: BoxConstraints.expand(width: 1.sw),
        scrollControlDisabledMaxHeightRatio: ratio,
        builder: (_) => PopupBottomRadioListView(
              data: data,
              initIndexs: initIndexs,
              isSingleSelect: isSingleSelect,
              title: title,
              cancelText: '取消',
              sureText: '确定',
              onSure: ((p0) {
                onSure(p0);
              }),
              itemHeight: itemHeight,
            ));
  }

  static FutureOr<T?> bottomWheel<T>({
    required List<String> data,
    ValueChanged<int>? onChange,
    ValueChanged<int>? onSure,
    TextStyle? unSelectedStyle,
    TextStyle? selectedStyle,
    int? initIndex,
  }) async {
    if (Get.context == null) return null;
    return showModalBottomSheet(
        context: Get.context!,
        constraints: BoxConstraints.expand(width: 1.sw),
        builder: (_) => PopupBottomWheelView(
              data: data,
              initIndex: initIndex,
              onChange: onChange,
              cancelText: '取消',
              sureText: '确定',
              onSure: onSure,
            ));
  }

  static FutureOr<int?> dropDown({
    required List<String> data,
    required GlobalKey sourceKey,
    List<dynamic>? prefixList,
    TextStyle? unSelectedStyle,
    TextStyle? selectedStyle,
    String? initValue,
    MainAxisAlignment? alignment,
    Widget Function(bool isUp)? childBuilder,
    double? width,
    double? itemHeight,
    EdgeInsets? padding,
  }) async {
    if (Get.context == null) return null;
    return showAdaptiveDialog(
        context: Get.context!,
        useSafeArea: false,
        builder: (_) => DropDownView(
              sourceKey: sourceKey,
              initialVal: initValue,
              list: data,
              prefixList: prefixList,
              alignment: alignment,
              itemHeight: itemHeight ?? 32.r,
              width: width ?? 115.r,
              padding: padding,
              childBuilder: childBuilder,
            ));
  }

  static FutureOr<int?> dropDownOption({
    required List<String> data,
    required GlobalKey sourceKey,
    required void Function(List<int> all) onChanged,
    List<int>? selected,
    bool mutilable = true,
    double? width,
    double? right,
    Color? bgColor,
  }) async {
    if (Get.context == null) return null;
    return showAdaptiveDialog(
        context: Get.context!,
        useSafeArea: false,
        builder: (_) => DropDownOptionView(
              sourceKey: sourceKey,
              list: data,
              width: width ?? 205.r,
              right: right,
              bgColor: bgColor,
              onChanged: onChanged,
              selected: selected,
              mutilable: mutilable,
            ));
  }

  static void snackBar({
    required String title,
    Widget? titleIcon,
    TextStyle? titleStyle,
    String? msg,
    Widget? msgChild,
    Duration? duration = const Duration(seconds: 3),
    Widget? action,
    VoidCallback? onAction,
  }) async {
    Get.snackbar(
      '',
      msg ?? '',
      titleText: Row(
        children: [
          if (titleIcon != null) titleIcon,
          Text(
            title,
            style: titleStyle ?? ITheme.text.title16,
          ),
        ],
      ),
      messageText: msgChild,
      mainButton:
          action == null ? null : TextButton(onPressed: () {}, child: action),
      duration: duration,
    );
  }

  static void notice({
    required Widget child,
  }) async {
    if (Get.context == null) return;

    Navigator.of(Get.context!).push(PageRouteBuilder(
      pageBuilder: (context, animation, secondaryAnimation) {
        return NoticeView(
          child: child,
        );
      },
      transitionsBuilder: (context, animation, secondaryAnimation, child) {
        return SlideTransition(
          position: Tween<Offset>(
            begin: const Offset(0.0, -0.2),
            end: const Offset(0.0, 0.0),
          ).animate(animation),
          child: child,
        );
      },
      fullscreenDialog: true,
      opaque: false,
      barrierDismissible: true,
    ));

    // return Get.to(
    //   () => NoticeView(),
    //   transition: Transition.upToDown,
    //   fullscreenDialog: true,
    //   opaque: false,
    //   popGesture: true,
    // );
    // showGeneralDialog(
    //     context: Get.context!,
    //     barrierDismissible: true,
    //     barrierLabel: 'Barrier',
    //     transitionDuration: Duration(milliseconds: 200),
    //     pageBuilder: (BuildContext context, Animation<double> animation,
    //         Animation<double> secondaryAnimation) {
    //       return Align(
    //         alignment: Alignment.topCenter,
    //         child: AnimatedBuilder(
    //           animation: animation,
    //           builder: (context, child) {
    //             return Transform.translate(
    //               offset: Offset(0.0, animation.value * 100),
    //               child: NoticeView(),
    //             );
    //           },
    //         ),
    //       );
    //     });
  }

  static _getBottomRatio({
    double? itemHeight,
    required int length,
  }) {
    var itemH = itemHeight ?? Popup.itemHeight;
    var totalH = itemH * length;
    var ratio = min(_defaultScrollControlDisabledMaxHeightRatio,
        (totalH + Get.mediaQuery.padding.bottom) / 1.sh);
    return ratio;
  }
}
